﻿#ifndef ESS_SINGLE_H
#define ESS_SINGLE_H

#include <QObject>
#include <QtCore>
#include <QtGui>
#include <QDateTime>
#include<QToolButton>
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#include<QMouseEvent>
#endif

#include "sqlConnect/ConnectionPool.h"
#include "singleProject/single_project.h"
#include "httpserver/httpconnection.h"


#define remainder 5                /***计时器求余***/
#define freeStatus 0                 /***空闲状态***/

#define workStationIN 31
#define workStationOUT 35

#define WaittingStationrun 7        //判断点等待放行
#define WaittingStationrun2 11      //暂存位等待放行


#define taskTakeMES_wait 6          /***MES 等待放行状态***/
#define taskTake_wait 2             /***ESS 等待放行状态***/
#define taskTake_run 7              /***接收到MES放行,开始放行***/

#define taskTake_wait2 18             /***ESS 等待放行状态***/
#define taskTake_run2 10             /***接收到MES放行,开始放行***/

#define taskStatus_delete 90         /***任务删除时的状态  解绑库位***/
#define taskStatus_delete_ 92        /***任务删除时的状态  解绑码头***/

#define taskFnish_not  99             /***总任务完成***/
#define taskFnish  100               /***总任务完成***/

//夹抱任务状态
#define PENDING "PENDING"
#define PROCESSING "PROCESSING"
#define SUSPEND "SUSPEND"
#define FINISHED "FINISHED"
#define CANCELLED "CANCELLED"
#define FAILED_ESS "FAILED"


//#define hongtu_AAREA "A站点上层"



class ESS_Single : public QObject
{
    Q_OBJECT

public:
    static QMutex mutex;
    static ESS_Single* ESS_SingleItiem;

    static ESS_Single *GetInstance();
    explicit ESS_Single(QObject *parent = nullptr);

    void setCurrentServerItem(ServerItem CServerItem,ServerInit CServerInit);

    //接驳台的任务信息
    QMap<QString,deviceI>stationInfoMap;
    void setStationInfoMap(QMap<QString,deviceI>stationInfoMapI);                     //更新基础信息: 是否离线
    QMap<QString,deviceI> getstationInfoMap_Map();                                      //获取当前设备信息

    QMap<QString, int>RunTask_Client;
    bool setRunTask(QString taskId,int  action);                    //设置平板放行链表
    int  getMESRunTask(QString taskId);                             //获取 平板放行链表

    /******************* ******************/
    QMap<QString, RunTaskData>RunTaskMap;
    bool setRunTaskMap(QString taskId, RunTaskData RunTaskDataI);   //设置平板放行链表
    RunTaskData getMESRunTaskMap(QString taskId);                   //获取 平板放行链表

    //创建 MES 缓存列表
    QMap<QString, SAPExcelInfo>newSAPExcelInfoList;
    bool setNewSAPExcelInfoList(SAPExcelInfo SAPExcelInfoI);
    QMap<QString, SAPExcelInfo> getNewSAPExcelInfoList();

    QMap<int, SAPExcelInfo>seletSAPExcelInfoTask;
    void setCurrentSAPExcelInfoTask(QMap<int, SAPExcelInfo>seletSAPExcelInfoTask_);               //获取SAP任务链表
    QMap<int, SAPExcelInfo> getCurrentSAPExcelInfoTask();               //获取SAP任务链表

    QMap<QString,AGVCurrentTask>AGVCurrentTaskMap;        //当前AGV状态信息
    void setAGVCurrentTaskMap(QMap<QString, AGVCurrentTask>AGVCurrentTaskMap_);
    QMap<QString, AGVCurrentTask> getAGVCurrentTaskMap();


    QMap<QString,shelfBinInfo>shelfBinInfoMap;                          //实时更新 Bin 的状态信息
    QMap<QString,shelfBinInfo>getshelfBinInfoMap(QString taskType,QString queryLineEdit,QString containerCode);

    shelfBinInfo getshelfBinInfo_Empty(SAPExcelInfo SAPExcelInfoI);     //入库时获取空闲的 库位
    shelfBinInfo getcontainerCode_desc(QString containerCode);          //出库时获取当前胶箱库位

    QMap<QString,LiftCode>LiftCodeMap;
    void setLiftCodeMap(QMap<QString,LiftCode>LiftCodeMap_);            //更新升降机各个接驳台状态信息
    QMap<QString,LiftCode> getLiftCodeMap();


    //**********************************MES 的所有位置状态管理********************************//

    QMap<int,CodeStatus>getCodeStatusMap();                                 //获取 MES 的所有位置状态

    bool setCodeStatus_SAP(QList<CodeStatus>CodeStatusList);                //更新 根据SAP任务更新 状态信息

    CodeStatus getCodeStatus_CarRun(QString deviceDesc);                    //获取 更新上下位机的放行信息

    bool setCodeStatus_CarRun(CodeStatus CodeStatusI);                      //更新 更新上下位机的放行信息


    //********************************** Modbus 数据处理********************************//
    ModbusAll _ModbusAllData;                                   // Modbus 状态信息

    void setModbusAllData(ModbusAll ModbusAllData);             //更新 Modbus 状态信息

    ModbusAll getModbusAllData();                               //获取 Modbus 状态信息

public:

    //提交单个 ESS 任务
    ESS_Request setESS_RequestI(SAPExcelInfo SAPExcelInfoI,ESS_Request ESS_RequestI,QString actionId,int taskAgvNum,int WaitStation);

    QMap<QString,QString> CurrentESS_RepostMap;
    bool setCurrentESS_Repost(QString taskId_ess,QString eventCodeDesc);      //实时监听并获取ESS_任务状态

    QString getCurrentESS_Repost(QString taskId_ess);                      //更新ESS_任务状态 到 task

    //把SAP 任务状态 转换为post 并实时更新更新到 MES
    WWYLPOST MES_WWYLPOSTI(SAPExcelInfo SAPExcelInfoI,QString actionId);


public:

    ServerInit ServerInitItem;      //基础信息
    ServerItem CurrentServerItem;   //需要实时更信息 链表表 整合

    QString currentUserNuber="";
    QMap<int ,sapPath >sapPathMap;


    ///新马SMA 仓库中转点状态
    ///deviceI 数据库表保存状态
    enum stationStatusEnum
    {
        station_Empty      = 0,     //空位
        station_EmptyPod   = 1,     //有架子
        station_FullPod    = 2,     //有料架子
        //        cameraStatus_Error      = 3,     //异常
    };
    struct stationStatusStruct
    {
        QString station;
        stationStatusEnum status;
        QDateTime updateDateTime;
    };

    QMap<QString, stationStatusStruct> stationStatusMap;    //站点状态 QMap<站点名, 站点状态>

    void initStationStatus();           //初始化状态
    bool getStationStatusByStationName(QString station, stationStatusStruct &status) const;    //获取站点状态

    QMap<QString, stationStatusStruct> getAllStationStatusMap() const;     //获取站点状态

    bool updateStationStatus(QString station, stationStatusEnum status);    //更新站点状态，包含更新到数据库
    ///end 新马SMA 仓库中转点状态

    //
    void setStationStatusMAP(QJsonValue value,QJsonArray rootFruitList);
    bool updateStationStatusMAP(QMap<QString, stationStatusStruct> stationStatusMap_);    //更新站点状态，包含更新到数据库
    ///end 新马SMA 仓库中转点状态


    /*************** 东莞拓安信物联 ***************/
    /**
     * @brief getIOStatus -判断 index 位的 IO 的状态
     * @param status - IO 值
     * @param index -第几位
     * @return true为1，flase为0
     */
    bool getIOStatus(quint64 status, int index);

    /**
     * @brief setMoveTask -创建 AGV 移动任务
     * @param SAPExcelInfoI -任务参数集合
     * @param station -移动到的目标站点
     * @param taskType -移动类型   正常：MOVE  回待机点：RUN
     * @param moveFlag -0：顶盘保持 1：降下移动 2：举升移动
     * @param flag -false：无操作 true：顶盘降下前往目标位置
     */
    void setMoveTask(SAPExcelInfo SAPExcelInfoI, int station, QString taskType, int moveFlag = 0, bool flag = false);

    /**
     * @brief setActionTask -创建 AGV 动作任务
     * @param SAPExcelInfoI -任务参数集合
     * @param station -移动到的目标站点
     * @param actionCode -动作命令 4：顶盘举升 3：顶盘下降
     * @param taskType -动作类型   正常：Action  回待机点：Delete
     * @param moveFlag -0：顶盘保持 1：降下移动 2：举升移动
     * @param flag -false：无操作 true：顶盘降下前往目标位置
     */
    void setActionTask(SAPExcelInfo SAPExcelInfoI, int station, int actionCode, QString taskType, int moveFlag = 0, bool flag = false);

    /**
     * @brief setRunActionTask -创建 AGV 放行任务
     * @param SAPExcelInfoI -任务参数集合
     */
    void setRunActionTask(SAPExcelInfo SAPExcelInfoI);

    /**
     * @brief setCancelTask -创建 AGV 取消任务
     * @param SAPExcelInfoI -任务参数集合
     */
    void setCancelTask(SAPExcelInfo SAPExcelInfoI);

    /**
     * @brief setAgvMusic -创建 AGV 设置语音任务
     * @param AgvNum -AGV 编号
     * @param MusicNum -语音编号
     */
    void setAgvMusicTask(int AgvNum, int MusicNum);

    /**
     * @brief setAgvClearTraffControlTask -创建 AGV 清除管制任务
     * @param AgvNum -AGV 编号 0：清除所有AGV 非0：清除指定AGV
     */
    void setAgvClearTraffControlTask(int AgvNum);

    /**
     * @brief setAgvCancelTask -取消指定AGV全部任务指令
     * @param AgvNum -AGV 编号
     */
    void setAgvCancelTask(int AgvNum);

    /**
     * @brief setSAPExcelInfo_New -任务数据封装
     * @param taskType  -任务类型 Move Action
     * @param taskTypeDesc -任务类型描述
     * @param taskId -任务编码
     * @param agvNum -AGV编号
     * @param load -起始站点备注
     * @param loadPoint -起始站点
     * @param unload -目标站点备注
     * @param unloadPoint -目标站点
     * @return
     */
    SAPExcelInfo setSAPExcelInfo_New(QString taskType, QString taskTypeDesc, QString taskId,
                                     int agvNum, QString load, int loadPoint, QString unload, int unloadPoint);

    //容器写入数据
    void Map_write();

    //任务先后计数
    QString Task_Count();

    // 翻译文件对象
    QTranslator trans;

    //翻译语言
    QString _language="";

    //库位名称描述容器
    QMap<QString,QString>_StationNameDescMap;

    //库位状态描述容器
    QMap<int,QString>_StationStatusDescMap;

    //接口响应状态描述容器
    QMap<int,QString>errorMsgMap;
    QMap<int,QString>_errorMsgMap;

    int _count = 0;
};

#endif // ESS_SINGLE_H
